package nuig.prolog.PrologAccess;

import java.io.FileInputStream;
import java.util.concurrent.Callable;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.FutureTask;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.TimeoutException;

import alice.tuprolog.MalformedGoalException;
import alice.tuprolog.Prolog;
import alice.tuprolog.SolveInfo;
import alice.tuprolog.Theory;

public class BaseProcess {
	// 单例模式，引擎和路径是唯一不变的
	public static Prolog engine;

	public static String path = "Main.pl";
	public static String answer="";
	private Theory theory;
	public SolveInfo info;

	public String ruleString;
	public String Type;

	public BaseProcess() throws Exception {
		try {
			engine = new Prolog();
			String p = this.getClass().getClassLoader().getResource("/")
					.getPath()
					+ path;
			theory = new Theory(new FileInputStream(p));
			engine.setTheory(theory);
		} catch (Exception e) {
			System.out.println(e.getMessage());
			throw e;

		}

	}

	/**
	 * 
	 * @return
	 * @throws MalformedGoalException
	 */
	public boolean isSuccess() throws MalformedGoalException {
		return  isSuccess( Type,  ruleString);
	}

	public boolean isSuccess(String ruleString) throws MalformedGoalException {

		this.ruleString=ruleString;
		return isSuccess( Type,  ruleString);
	}
	
	

	
	
	public boolean isSuccess(String Type, String ruleString) {
		this.Type=Type;
		
		if (null == ruleString || 0 == ruleString.length()) {
			return false;
		} else {
			try {
				StringBuilder builder = new StringBuilder();
				builder.append("phrase(").append(Type).append(",[")
						.append(ruleString).append("]).");
				this.answer = builder.toString();
				
				return executeIsSuccess();
				
			} catch (Exception e) {
				System.out.println(e.getMessage());
			}
			return false;
		}

	}
	
	class Process implements Callable{
		@Override
		public Object call() throws Exception {
			info = getEngine().solve(answer);
			return info.isSuccess();
		}
	}
	
	public boolean executeIsSuccess()
	{
		Process p=new Process();
		Thread t = null;
		final FutureTask future = new FutureTask(p);
		t = new Thread(future);
		t.start();
		try {
			Object o= future.get(1, TimeUnit.SECONDS);
			return Boolean.parseBoolean(o.toString());
		} catch (InterruptedException e1) {
			t.stop();
			//e1.printStackTrace();
		} catch (ExecutionException e1) {
			t.stop();
			//e1.printStackTrace();
		} catch (TimeoutException e1) {
			t.stop();
			//e1.printStackTrace();
		}
		return false;
	}

	/*
	 * get set
	 */

	public Theory getTheory() {
		return theory;
	}

	public void setTheory(Theory theory) {
		this.theory = theory;
	}

	public static Prolog getEngine() {
		if (engine == null) {
			engine = new Prolog();
		}
		return engine;
	}

	public static void setEngine(Prolog engine) {
		BaseProcess.engine = engine;
	}



	/*
	 * end of get set
	 */

}
